classdef TestDotsTheDrawablesManager < dotsTestCase
    
    properties
        dm;
        functionCount;
    end
    
    methods
        function self = TestDotsTheDrawablesManager(name)
            self = self@dotsTestCase(name);
        end
        
        function setUp(self)
            self.setUp@dotsTestCase;
            
            dotsTheDrawablesManager.reset;
            self.dm = dotsTheDrawablesManager.theObject;
            
            self.functionCount = 0;
        end
        
        function functionMayHappen(self)
            self.functionCount = self.functionCount + 1;
        end
        
        function testNew(self)
            className = 'dotsDrawableTargets';
            object = self.dm.newObject(className);
            assertEqual(class(object), className, ...
                sprintf('should have new %s instance', className));
        end
        
        function testIsAnimating(self)
            self.dm.openScreenWindow;
            
            isAnimating = true;
            self.dm.mayDrawNextFrame(isAnimating);
            assertEqual(self.dm.isAnimating, isAnimating, ...
                'mayDrawNextFrame() should use isAnimating flag');
            
            isAnimating = false;
            self.dm.mayDrawNextFrame(isAnimating);
            assertEqual(self.dm.isAnimating, isAnimating, ...
                'mayDrawNextFrame() should use isAnimating flag');
            
            self.dm.closeScreenWindow;
        end
        
        function testDrawNextFrame(self)
            className = 'dotsDrawableTargets';
            object = self.dm.newObject(className);
            
            group = 'testDraw';
            self.dm.addObjectToGroup(object, group);
            self.dm.activateGroup(group);
            
            self.dm.openScreenWindow;
            assertTrue(self.dm.getScreenDisplayNumber() >= 0, ...
                'should have a window open on a display')
            
            % must report increasing flip times
            n = 10;
            onset = zeros(1,n);
            number = zeros(1,n);
            swap = zeros(1,n);
            for ii = [1:n 1:n]
                frameInfo = self.dm.mayDrawNextFrame();
                onset(ii) = frameInfo.onsetTime;
                number(ii) = frameInfo.onsetFrame;
                swap(ii) = frameInfo.swapTime;
            end
            
            for ii = 2:n
                assertTrue(onset(ii) >= onset(ii-1), sprintf( ...
                    '%dth onset time %f should be greater than %f', ...
                    ii, onset(ii), onset(ii-1)));
                assertTrue(number(ii) >= number(ii-1), sprintf( ...
                    '%dth frame number %f should be greater than %f', ...
                    ii, number(ii), number(ii-1)));
                assertTrue(swap(ii) >= swap(ii-1), sprintf( ...
                    '%dth swap time %f should be greater than %f', ...
                    ii, swap(ii), swap(ii-1)));
            end
            
            self.dm.closeScreenWindow;
        end
        
        function testActiveGroup(self)
            className = 'dotsDrawableTargets';
            object = self.dm.newObject(className);
            
            group = 'testDraw';
            self.dm.addObjectToGroup(object, group);
            self.dm.activateGroup(group);
            drawGroup = self.dm.activeDrawables;
            assertEqual(object, drawGroup{1}, ...
                'new object should be in active array')
        end
        
        function testScreenProperties(self)
            self.dm.openScreenWindow;
            
            theScreen = dotsTheScreen.theObject;
            shared = theScreen.sharedProperties;
            for ii = 1:length(shared)
                assertFalse(isempty(self.dm.(shared{ii})), ...
                    sprintf('should have received %s from theScreen', ...
                    shared{ii}));
            end
            
            self.dm.closeScreenWindow;
        end
        
        function testScreenOpenClose(self)
            self.dm.openScreenWindow;
            assertTrue(self.dm.getScreenDisplayNumber() >= 0, ...
                'dotsTheScreen should report a window open on a display')
            
            self.dm.closeScreenWindow;
            assertTrue(self.dm.getScreenDisplayNumber() < 0, ...
                'dotsTheScreen should report no window open')
        end
        
        function testSetGetScreenProperty(self)
            property = 'windowRect';
            oldValue = self.dm.getScreenProperty(property);
            
            setValue = [100 100 200 200];
            self.dm.setScreenProperty(property, setValue);
            
            getValue = self.dm.getScreenProperty(property);
            assertEqual(getValue, setValue, ...
                'should set and get same value from dotsTheScreen')
            
            % defensive reassignment of old value
            self.dm.setScreenProperty(property, oldValue);
        end
    end
end